﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using zEngine;

namespace FYP.TestCases
{
    public class TestCaseManager
    {
        private Game _game;
        private List<TestCase> _testCases = new List<TestCase>();
        private int _currentIndex = -1;

        private bool _runContinuously = false;
        #region Properties
        public TestCase CurrentTestCase
        {
            get
            {
                if (_currentIndex >= 0 && _currentIndex < _testCases.Count)
                {
                    return TestCases[_currentIndex];
                }
                return null;
            }
        }

        public int CurrentIndex
        {
            get { return _currentIndex; }
            set { _currentIndex = value; }
        }

        public List<TestCase> TestCases
        {
            get { return _testCases; }
            set { _testCases = value; }
        }
        public Game Game
        {
            get { return _game; }
            set { _game = value; }
        }
        public bool RunContinuously
        {
            get { return _runContinuously; }
            set { _runContinuously = value; }
        }
        #endregion

        /// <summary>
        /// Initializes a new instance of the TestCaseManager class.
        /// </summary>
        /// <param name="game"></param>
        public TestCaseManager(Game game)
        {
            _game = game;
        }
        
        public void Update(GameTime gameTime)
        {
            if (CurrentTestCase == null && _testCases.Count > 0)
            {
                SwitchTest(gameTime, 0);
            }
            if (CurrentTestCase != null)
            {
                CurrentTestCase.Update(gameTime);
                if (CurrentTestCase.IsFinish && _runContinuously && CurrentTestCase.DataManager.IsSaved)
                {
                    if (_currentIndex < _testCases.Count - 1)
                    {
                        SwitchTest(gameTime, _currentIndex + 1);
                    }
                }
            }
        }

        public void Draw(GameTime gameTime)
        {
            if (CurrentTestCase != null)
                CurrentTestCase.Draw(gameTime);
        }

        /// <summary>
        /// Remove the specific type of test
        /// </summary>
        /// <param name="oldStateType"></param>
        public void Remove(Type oldTestCaseType)
        {
            int removeID = -1;
            for (int i = 0; i < TestCases.Count; i++)
            {
                if (TestCases[i].GetType() == oldTestCaseType)
                {
                    removeID = i;
                    break;
                }
            }
            if (removeID > -1)
            {
                TestCases.RemoveAt(removeID);
            }
        }

        /// <summary>
        /// Add a new test to the list
        /// </summary>
        public void Add(TestCase newTest)
        {
            newTest.Parent = this;
            TestCases.Add(newTest);
        }

        /// <summary>
        /// Switch to the state with the same input type
        /// </summary>
        /// <param name="StateType"></param>
        public TestCase SwitchTest(GameTime gameTime, Type TestType)
        {
            for (int idx = 0; idx < TestCases.Count; idx++)
            {
                if (TestCases[idx].GetType() == TestType)
                {
                    return SwitchTest(gameTime, idx);
                }
            }

            return null;
        }

        public TestCase SwitchTest(GameTime gameTime, TestCase thisTest)
        {
            for (int idx = 0; idx < TestCases.Count; idx++)
            {
                if (TestCases[idx] == thisTest)
                {
                    return SwitchTest(gameTime, idx);
                }
            }

            return null;
        }

        /// <summary>
        /// Switch to the input index test
        /// </summary>
        /// <param name="idx"></param>
        public TestCase SwitchTest(GameTime gameTime, int idx)
        {
            if(CurrentTestCase != null)
                CurrentTestCase.TestOff(gameTime);

            _currentIndex = idx;
            CurrentTestCase.TestOn(gameTime);
            return CurrentTestCase;
        }

    }
}
